package com.neuronbit.businessflow.intellij;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import org.cef.callback.CefCallback;
import org.cef.handler.CefResourceHandler;
import org.cef.misc.IntRef;
import org.cef.misc.StringRef;
import org.cef.network.CefRequest;
import org.cef.network.CefResponse;

import java.io.IOException;
import java.io.InputStream;

/**
 * The type Bpm cef resource handler.
 */
public class BpmCefResourceHandler implements CefResourceHandler, Disposable {
    private final InputStream myStream;
    private final String myMimeType;
    private final Disposable parent;

    /**
     * Instantiates a new Bpm cef resource handler.
     *
     * @param myStream   the my stream
     * @param myMimeType the my mime type
     * @param parent     the parent
     */
    public BpmCefResourceHandler(InputStream myStream, String myMimeType, Disposable parent) {
        this.myStream = myStream;
        this.myMimeType = myMimeType;
        this.parent = parent;
        Disposer.register(parent, this);
    }

    @Override
    public boolean processRequest(CefRequest request, CefCallback callback) {
        callback.Continue();
        return true;
    }

    @Override
    public void getResponseHeaders(CefResponse response, IntRef responseLength, StringRef redirectUrl) {
        response.setMimeType(myMimeType);
        response.setStatus(200);
    }

    @Override
    public boolean readResponse(byte[] dataOut, int bytesToRead, IntRef bytesRead, CefCallback callback) {
        try {
            bytesRead.set(myStream.read(dataOut, 0, bytesToRead));
            if (bytesRead.get() != -1) {
                return true;
            }
        } catch (IOException e) {
            callback.cancel();
        }
        bytesRead.set(0);
        Disposer.dispose(this);
        return false;
    }

    @Override
    public void cancel() {
        Disposer.dispose(this);
    }

    @Override
    public void dispose() {
        try {
            myStream.close();
        } catch (IOException e) {
            Logger.getInstance(BpmCefResourceHandler.class).warn("Failed to close the stream", e);
        }
    }
}
